using AjaxControlToolkit;
using FreeTextBoxControls;
using System;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace NimblePros.SimpleCms
{
    class EditPage : CmsPageBase
    {
        #region fields
        private HtmlHead _head;
        private HtmlGenericControl _body;
        private HtmlForm _form;
        private ScriptManager _scriptManager;
        private HoverMenuExtender _hoverExtender;
        private TextBoxWatermarkExtender _urlWaterExtender;
        private TextBoxWatermarkExtender _titleWaterExtender;
        private Panel _header;
        private HtmlTable _table;
        private Label _errorMessage;
        private TextBox _titleBox;
        private TextBox _urlBox;
        private Image _urlToolTipImage;
        private Panel _urlToolTip;
        private TextBox _description;
        private TextBox _keywords;
        private string _textBoxText;
        private CheckBox _enabledBox;
        private TextBox _masterPage;
        private Button _save;
        private Button _saveView;
        private Button _cancel;
        #endregion

        public EditPage()
        {
        }

        #region Create and Populate Controls

        protected void AddControlsToFormAndPage()
        {
            _form.Controls.Add(_scriptManager);
            _form.Controls.Add(_errorMessage);
            _form.Controls.Add(_header);
            _form.Controls.Add(_table);
            _form.Controls.Add(GetVersionInfo());
            _form.Controls.Add(_urlToolTip);
            _form.Controls.Add(_hoverExtender);
            _form.Controls.Add(_urlWaterExtender);
            _form.Controls.Add(_titleWaterExtender);
            _body.Controls.Add(_form);
            this.Controls.Add(_head);
            this.Controls.Add(_body);
        }

        protected void AddReferenceForCkEditorJavaScript()
        {
            HtmlGenericControl ckTextBoxReference = new HtmlGenericControl("script");
            ckTextBoxReference.Attributes["type"] = "text/javascript";
            ckTextBoxReference.Attributes["src"] = "/ckeditor/ckeditor.js";
            _head.Controls.Add(ckTextBoxReference);

        }

        protected void AddStyleSheet()
        {
            HtmlLink cssLink = new HtmlLink
            {
                Href = ClientScript.GetWebResourceUrl(this.GetType(), "NimblePros.SimpleCms.styles.css"),
            };
            cssLink.Attributes.Add("rel", "stylesheet");
            cssLink.Attributes.Add("type", "text/css");

            _head.Controls.Add(cssLink);
        }

        protected void CreateControls()
        {
            _head = new HtmlHead { Title = "Simple CMS Edit", };

            _body = new HtmlGenericControl("body");

            _form = new HtmlForm { ID = "frm", Method = "post" };
            _form.Attributes.Add("onsubmit", "return ValidateForm()");

            _scriptManager = new ScriptManager
            {
                EnablePartialRendering = true,
                ID = "sm1",
            };

            _hoverExtender = new HoverMenuExtender
            {
                ID = "he1",
                PopupControlID = "urlpop",
                TargetControlID = "urlhover",
                PopupPosition = HoverMenuPopupPosition.Bottom,
                PopDelay = 50,
            };

            _titleWaterExtender = PopulateWatermarkExtender("twe");
            _urlWaterExtender = PopulateWatermarkExtender("uwe");
            
            CreateHeader();

            _table = new HtmlTable { Border = 0 };
            _table.Style.Add("width", "100%");

            _errorMessage = new Label { ID = "ErrorMessage", Visible = false, };

            _urlToolTipImage = new Image
            {
                ID = "urlhover",
                ImageUrl = this.ClientScript.GetWebResourceUrl(this.GetType(), "NimblePros.SimpleCms.Images.info.gif"),
                AlternateText = "[Helpful Tips]",
            };
            _urlToolTipImage.Style.Add("float","right");
            _urlToolTipImage.Style.Add("margin-right", "5px");

            _urlToolTip = new Panel { ID = "urlpop", Width = new Unit("45%"), CssClass = "tip", };
            _urlToolTip.Controls.Add(new LiteralControl("Please enter the absolute path and name of your page here. If editing a page, changing this path will move your page to the new path."));
            _urlToolTip.Style.Add("visibility", "hidden");
            _urlToolTip.Style.Add("display", "none");


            _enabledBox = new CheckBox { Text = "Enabled", ID = "Enabled", Checked = true, };

            _masterPage = PopulateMasterPageTextBox("MasterPage");
            _keywords = PopulateKeywordTextBox("Keywords");
            _description = PopulateDescriptionTextBox("description");
            _titleBox = PopulateTitleTextBox("TitleBox");
            _urlBox = PopulateUrlTextBox("UrlBox");

            _cancel = PopulateButton("cancel", "Cancel");
            _save = PopulateButton("save", "Save");
            _saveView = PopulateButton("saveview", "Save and View");
        }

        protected void CreateHeader()
        {
            _header = new Panel();
            _header.CssClass = "header";
            _header.Style.Add("background", "#910000 url('" + ClientScript.GetWebResourceUrl(this.GetType(), "NimblePros.SimpleCms.Images.header-bkgd.gif") + "') bottom");

            Panel headerTitle = new Panel();
            headerTitle.CssClass = "headerTitle";

            headerTitle.Controls.Add(new LiteralControl("Simple CMS v" + Assembly.GetExecutingAssembly().GetName().Version.ToString()));

            Panel newPage = new Panel();
            newPage.CssClass = "newPage";
            newPage.Style.Add("background", "url('" + ClientScript.GetWebResourceUrl(this.GetType(), "NimblePros.SimpleCms.Images.newdoc.gif") + "') no-repeat");

            HyperLink topNewPage = new HyperLink();
            topNewPage.Text = "Create New Page";
            topNewPage.NavigateUrl = CmsConfig.EditPage;

            newPage.Controls.Add(topNewPage);

            _header.Controls.Add(headerTitle);
            _header.Controls.Add(newPage);
        }

        protected LiteralControl GetVersionInfo()
        {
            string version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
            string copyright = string.Empty;
            object[] customs = Assembly.GetExecutingAssembly().GetCustomAttributes(false);
            foreach (object eachAttribute in customs)
            {
                if (eachAttribute.GetType() == typeof(AssemblyCopyrightAttribute))
                {
                    AssemblyCopyrightAttribute copyobject = eachAttribute as AssemblyCopyrightAttribute;
                    copyright = copyobject.Copyright;
                }
            }

            return new LiteralControl(@"<div align='center' class='copyright'><strong>Simple CMS</strong> Version " + version + " " + copyright + "</div>");
        }

        protected void PopulateHtmlTable()
        {
            _table.Rows.Add(new HtmlTableRow());
            PopulatePageTitleCell();
            PopulatePagePathCell();

            _table.Rows.Add(new HtmlTableRow());
            PopulateDescriptionCell();
            PopulateKeywordCell();

            _table.Rows.Add(new HtmlTableRow());
            PopulatePageContentCell();

            _table.Rows.Add(new HtmlTableRow());
            PopulateBackgroundCell();
            PopulateMasterPageCell();
            PopulateSaveControlsCell();
        }

        protected void PopulatePageTitleCell()
        {
            _table.Rows[0].Cells.Add(new HtmlTableCell());
            _table.Rows[0].Cells[0].Controls.Add(new LiteralControl("<h6>" + "Page Title" + "</h6>"));
            _table.Rows[0].Cells[0].ColSpan = 2;
            _table.Rows[0].Cells[0].Controls.Add(_titleBox);
            _table.Rows[0].Cells[0].Width = "50%";
            _table.Rows[0].Cells[0].VAlign = "top";
        }

        protected void PopulatePagePathCell()
        {
            _table.Rows[0].Cells.Add(new HtmlTableCell());
            _table.Rows[0].Cells[1].Controls.Add(new LiteralControl("<h6>" + "Page Path" + "/Name</h6>"));
            _table.Rows[0].Cells[1].Controls.Add(_urlToolTipImage);
            _table.Rows[0].Cells[1].Controls.Add(_urlBox);
            _table.Rows[0].Cells[1].Width = "50%";
            _table.Rows[0].Cells[1].VAlign = "top";
        }

        protected void PopulateDescriptionCell()
        {
            _table.Rows[1].Cells.Add(new HtmlTableCell());
            _table.Rows[1].Cells[0].Controls.Add(new LiteralControl("<h6>" + "Description" + "</h6>"));
            _table.Rows[1].Cells[0].ColSpan = 2;
            _table.Rows[1].Cells[0].Controls.Add(_description);
            _table.Rows[1].Cells[0].Width = "50%";
            _table.Rows[1].Cells[0].VAlign = "top";
        }

        protected void PopulateKeywordCell()
        {
            _table.Rows[1].Cells.Add(new HtmlTableCell());
            _table.Rows[1].Cells[1].Controls.Add(new LiteralControl("<h6>" + "Keywords" + "</h6>"));
            _table.Rows[1].Cells[1].Controls.Add(_keywords);
            _table.Rows[1].Cells[1].Width = "50%";
            _table.Rows[1].Cells[1].VAlign = "top";
        }

        protected void PopulatePageContentCell()
        {
            _table.Rows[2].Cells.Add(new HtmlTableCell());
            _table.Rows[2].Cells[0].ColSpan = 3;
            _table.Rows[2].Cells[0].Controls.Add(new LiteralControl("<h6>" + "Page Content" + "</h6>"));
            //_table.Rows[2].Cells[0].Controls.Add(_contentBox);
            _table.Rows[2].Cells[0].Controls.Add(new LiteralControl("<textarea runat=\"server\" id=\"ContentBox\" name=\"ContentBox\">" +                                                                           _textBoxText + "</textarea>"));


            HtmlGenericControl ckEditorScript = new HtmlGenericControl("script");
            ckEditorScript.Attributes["type"] = "text/javascript";
            ckEditorScript.InnerHtml = "CKEDITOR.replace('ContentBox');";
            _table.Rows[2].Cells[0].Controls.Add(ckEditorScript);
        }

        protected void PopulateBackgroundCell()
        {
            _table.Rows[3].Cells.Add(new HtmlTableCell());
            _table.Rows[3].Cells[0].Controls.Add
                (new LiteralControl("<img src='" + ClientScript.GetWebResourceUrl(this.GetType(), "NimblePros.SimpleCms.                                               Images.enabled.gif") + "' alt='Enabled'>"));
            _table.Rows[3].Cells[0].Controls.Add(_enabledBox);
        }

        protected void PopulateMasterPageCell()
        {
            _table.Rows[3].Cells.Add(new HtmlTableCell());
            _table.Rows[3].Cells[1].Controls.Add(new LiteralControl("<h6>MasterPage</h6>"));
            _table.Rows[3].Cells[1].Controls.Add(_masterPage);
        }

        protected void PopulateSaveControlsCell()
        {
            _table.Rows[3].Cells.Add(new HtmlTableCell());
            _table.Rows[3].Cells[2].Controls.Add(_cancel);
            _table.Rows[3].Cells[2].Controls.Add(_save);
            _table.Rows[3].Cells[2].Controls.Add(_saveView);
        }

        protected Button PopulateButton(string buttonId, string buttonText)
        {
           return new Button { ID = buttonId, Text = buttonText};

        }

        protected TextBoxWatermarkExtender PopulateWatermarkExtender(string watermId)
        {
            TextBoxWatermarkExtender watermarkExtenderControl = new TextBoxWatermarkExtender();
            watermarkExtenderControl.ID = watermId;
            watermarkExtenderControl.WatermarkCssClass = "watermarked";

            if (watermId == "twe")
            {
                watermarkExtenderControl.TargetControlID = "TitleBox";
                watermarkExtenderControl.WatermarkText = "Enter a Title Here";
            }
            else
            {
                watermarkExtenderControl.WatermarkText = "Enter a Page Name Here (start with ~/)";
                watermarkExtenderControl.TargetControlID = "UrlBox";
            }

            return watermarkExtenderControl;
        }

        protected TextBox PopulateDescriptionTextBox(string textBoxId)
        {
            return new TextBox
            {
                TextMode = TextBoxMode.MultiLine,
                Columns = 40,
                Rows = 5,
                ID = textBoxId,
                CssClass = "inputFields",
                MaxLength = 500,
            };
                                 
        }

        protected TextBox PopulateKeywordTextBox(string textBoxId)
        {
            return new TextBox
            {
                TextMode = TextBoxMode.MultiLine,
                Columns = 40,
                Rows = 5,
                ID = textBoxId,
                CssClass = "inputFields",
                MaxLength = 500,
            };

        }

        protected TextBox PopulateMasterPageTextBox(string textBoxId)
        {
            return new TextBox
            {
                ID = textBoxId,
                CssClass = "inputFields",
                Text = CmsConfig.MasterPage,
                MaxLength = 200,
            };
        }

        protected TextBox PopulateTitleTextBox(string textBoxId)
        {
            return new TextBox
            {
                ID = textBoxId,
                CssClass = "inputFields",
                MaxLength = 200,
            };
        }

        protected TextBox PopulateUrlTextBox(string textBoxId)
        {
            return new TextBox
            {
                ID = textBoxId,
                CssClass = "inputFields",
                MaxLength = 200,
            };
        }

        #endregion

        protected override void OnPreInit(EventArgs e)
        {
            if (CmsConfig != null)
            {
                this.AppRelativeVirtualPath = CmsConfig.EditPage;
            }
            else
            {
                return;
            }

            CreateControls();
            AddStyleSheet();
            AddReferenceForCkEditorJavaScript();
            PopulateControlsWithCmsPageData();
            PopulateHtmlTable();
            AddControlsToFormAndPage();

            base.OnPreInit(e);
        }


        protected void PopulateControlsWithCmsPageData()
        {
            if (this.Request.QueryString[Resources.PageIdQueryString] != null)
            {
                int PageId = Convert.ToInt32(this.Request.QueryString[Resources.PageIdQueryString]);
                CmsPage pageData = new CmsPage(PageId);
                if (pageData != null)
                {
                    _urlBox.Text = pageData.Url;
                    _titleBox.Text = pageData.Title;
                    _description.Text = pageData.Description;
                    _keywords.Text = pageData.Keywords;
                    _textBoxText = pageData.ContentText;
                    _enabledBox.Checked = pageData.Enabled;
                    _masterPage.Text = pageData.MasterPage;
                }
            }
        }


        #region HandleUserInteractions

        protected void SaveButton_Click()
        {
            string ContentText = this.Request.Form["ContentBox"];
            string UrlBox = this.Request.Form["UrlBox"];
            string TitleBox = this.Request.Form["TitleBox"];
            string Description = this.Request.Form["Description"];
            string Keywords = this.Request.Form["Keywords"];
            string MasterPageBox = this.Request.Form["MasterPage"];
            bool Enabled;
            if (this.Request.Form["Enabled"] != null)
            {
                Enabled = true;
            }
            else
            {
                Enabled = false;
            }

            int PageId = 0;
            if (this.Request.QueryString[Resources.PageIdQueryString] != null)
            {
                PageId = Convert.ToInt32(Request.QueryString[Resources.PageIdQueryString]);
            }

            CmsPage myPage;

            if (Request.QueryString[Resources.PageIdQueryString] != null)
            {
                myPage = new CmsPage(Convert.ToInt32(Request.QueryString[Resources.PageIdQueryString]));
            }
            else
            {
                myPage = new CmsPage();
            }


            myPage.Url = UrlBox;
            myPage.Title = TitleBox;

            // Server Side Error Checking
            string Errors = ValidateForm(myPage, Convert.ToInt32(Request.QueryString[Resources.PageIdQueryString]));

            if (!string.IsNullOrEmpty(Errors))
            {
                _errorMessage.Visible = true;
                _errorMessage.Text = Errors;
                return;
            }

            myPage.Description = Description;
            myPage.Keywords = Keywords;
            myPage.ContentText = ContentText;
            myPage.Enabled = Enabled;
            myPage.MasterPage = MasterPageBox;
            myPage.Save(this);

            if (this.Request.Form["saveview"] != null)
            {
                Response.Redirect(this.Request.Form["UrlBox"], true);
            }
            else
            {
                Response.Redirect(CmsConfig.AdminPage, true);
            }
        }

        protected string ValidateForm(CmsPage myPage, int id)
        {
            string retval = string.Empty;
            if (!Regex.IsMatch(myPage.Url, @"^~/[0-9a-zA-Z_][0-9a-zA-Z/_-]*\.[0-9a-zA-Z_-]+$"))
            {
                retval += "Error: The Url field is required and must contain '~/' (ex: ~/default.cmsx).<br />";
            }

            // Make sure title exists
            if (string.IsNullOrEmpty(myPage.Title))
            {
                retval += "Error: A title must be specified.<br />";
            }

            // Check if URL already exists
            CmsPage checkPage = new CmsPage(myPage.Url);
            if (id > 0)
            {
                if (checkPage != null && id != checkPage.Id && myPage.Url == checkPage.Url)
                {
                    retval += "Error: This Url already exists in the system.<br />";
                }
            }
            else
            {
                if (checkPage != null && myPage.Url == checkPage.Url)
                {
                    retval += "Error: This Url already exists in the system.<br />";
                }
            }

            // Check if there is a file at that URL already
            string filePath = this.Server.MapPath(myPage.Url);
            try
            {
                if (System.IO.File.Exists(filePath))
                {
                    retval += "Error: A File with this name exists on the host server.<br />";
                }
            }
            catch
            {
                // Fail Silently
            }


            return retval;
        }

        #endregion

        protected override void Render(HtmlTextWriter writer)
        {
            if (this.IsPostBack)
            {
                if (this.Request.Form.GetValues("cancel") != null)
                {
                    Response.Redirect(CmsConfig.AdminPage);
                }
                else
                {
                    SaveButton_Click();
                }
            }

            writer.RenderBeginTag(HtmlTextWriterTag.Html);

            base.Render(writer);

            writer.RenderEndTag(); // </html>
        }

    }
}
